package ms.aurora.routing;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Router implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object sourceInstance = invocation.getThis();
        Class<?> sourceClass = sourceInstance.getClass();
        Method sourceMethod = invocation.getMethod();
        Object sourceResult = invocation.proceed();

        Field observerField = sourceClass.getField("observer");
        Route route = sourceMethod.getAnnotation(Route.class);
        if (!reroute(sourceInstance, observerField, route)) {
            System.err.println("WARNING: Re-routing failed because model "
                    + sourceClass.getName() + " has no observer attached.");
        }
        return sourceResult;
    }

    private boolean reroute(Object source, Field field, Route route) {
        try {
            ModelObserver observer = ((ModelObserver) field.get(source));
            observer.onModelChanged(route.attributeName());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
